package com.ksd.modules.rbac.menus.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ksd.common.enums.DeletedEnums;
import com.ksd.common.enums.StatusEnums;
import com.ksd.commons.BaseServiceImpl;
import com.ksd.modules.rbac.menus.entity.SysMenus;
import com.ksd.modules.rbac.menus.entity.SysRoleMenus;
import com.ksd.modules.rbac.menus.mapper.SysMenusMapper;
import com.ksd.modules.rbac.menus.mapper.SysRoleMenusMapper;
import com.ksd.modules.rbac.menus.service.ISysRoleMenusService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色菜单表 服务实现类
 * </p>
 *
 * @author Auto Generator
 * @since 2023-08-13
 */
@Service
public class SysRoleMenusService extends BaseServiceImpl<SysRoleMenusMapper, SysRoleMenus> implements ISysRoleMenusService {


    @Resource
    private SysMenusMapper sysMenusMapper;


    @Override
    public List<SysMenus> findMenu() {
        LambdaQueryWrapper<SysMenus> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysMenus::getHidden, StatusEnums.STATUS.getCode());
        lambdaQueryWrapper.eq(SysMenus::getIsDeleted, DeletedEnums.UN_DELETED.getCode());
        lambdaQueryWrapper.orderByAsc(SysMenus::getSort);
        //数据查询
        List<SysMenus> list = sysMenusMapper.selectList(lambdaQueryWrapper);
        //新建一个用于接收数据的list
        List<SysMenus> resultList = new ArrayList<>();
        for (SysMenus result : list) {
            if (result.getParentId() == 0L) {
                //调用方法给子类添加数据
                resultList.add(getMenuTree(result, list));
            }
        }
        return resultList;
    }

    private SysMenus getMenuTree(SysMenus result, List<SysMenus> list) {
        for (SysMenus menu : list) {
            //如果父类主键等于传过来实体类的ID
            if (menu.getParentId() == result.getId()) {
                if (result.getChildren() == null) {
                    result.setChildren(new ArrayList<>());
                }
                // 递归调用
                result.getChildren().add(getMenuTree(menu, list));
            }
        }
        return result;
    }


    /**
     * 查询角色授权的菜单信息
     *
     * @return
     */
    @Override
    public List<SysMenus> findRolesMenu(Long roleId) {
        LambdaQueryWrapper<SysRoleMenus> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysRoleMenus::getRoleId, roleId);
        List<SysRoleMenus> menus = this.list(lambdaQueryWrapper);
        if (CollectionUtils.isNotEmpty(menus)) {
            List<Long> menuIds = menus.stream().map(c -> c.getMenuId()).collect(Collectors.toList());
            LambdaQueryWrapper<SysMenus> menusLambdaQueryWrapper = new LambdaQueryWrapper<>();
            menusLambdaQueryWrapper.in(SysMenus::getId, menuIds);
            return sysMenusMapper.selectList(menusLambdaQueryWrapper);
        }
        return null;
    }

    /**
     * 授权信息
     *
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveRoleMenus(Long roleId, String menuIds) {
        // 1: 先删除用户的角色
        LambdaQueryWrapper<SysRoleMenus> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysRoleMenus::getRoleId, roleId);
        this.remove(lambdaQueryWrapper);
        // 2：准备开始授权
        if (StringUtils.isNotEmpty(menuIds)) {
            String[] menuIdsArray = menuIds.split(",");
            List<SysRoleMenus> roleMenusList = Arrays.stream(menuIdsArray).map(Long::parseLong).map(mid -> {
                SysRoleMenus sysRoleMenus = new SysRoleMenus();
                sysRoleMenus.setRoleId(roleId);
                sysRoleMenus.setMenuId(mid);
                return sysRoleMenus;
            }).collect(Collectors.toList());
            // 批量保存角色菜单信息
            this.saveBatch(roleMenusList);
        }
        return true;
    }

}
